package com.alibaba.citrus.cr.mn.order.center.facade.function.assemble.impl.returnorder;

import com.alibaba.citrus.cr.common.enums.ordercenter.DictionaryTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.*;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.request.ShipToPartyByAccurateQueryRequest;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.request.SoldToPartyByAccurateQueryRequest;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.response.BusinessChannelDTO;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.response.BusinessUnitDTO;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.response.ShipToPartyByAccurateQueryDTO;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.response.SoldToPartyByAccurateQueryDTO;
import com.alibaba.citrus.cr.mn.order.center.facade.function.assemble.OrderBizAssemble;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.mnordercenter.model.dto.DictionaryResponse;
import com.epoch.app.mnordercenter.model.dto.ReturnOrderBizCreateRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomCreateRequest;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhangxiaorui
 * @ClassName OrderBizAssembleOfMember
 * @description: TODO
 * @date 2023/05/17 09:49
 * @version: 1.0
 */
@Service
@Order(4)
public class ReturnOrderBizAssembleOfCustomerCenter implements OrderBizAssemble<ReturnOrderBizCreateRequest> {
    private static final Log log = Log.getLogger(ReturnOrderBizAssembleOfCustomerCenter.class);

    @Resource
    private SoldToPartyAbilityAdapter soldToPartyAbilityAdapter;
    @Resource
    private ShipToPartyAbilityAdapter shipToPartyAbilityAdapter;
    @Resource
    private SalesOrgAbilityAdapter salesOrgAbilityAdapter;
    @Resource
    private BusinessUnitAbilityAdapter businessUnitAbilityAdapter;
    @Resource
    private BusinessChannelAbilityAdapter businessChannelAbilityAdapter;
    @Resource
    private CustomerCenterAdapter customerCenterAdapter;
    @Resource
    private BaseDataServiceAdapter baseDataServiceAdapter;

    @Override
    public Map<String, Object> query(ReturnOrderBizCreateRequest bizCreateRequest) {
        return query(Lists.newArrayList(bizCreateRequest));
    }

    @Override
    public Map<String, Object> query(List<ReturnOrderBizCreateRequest> bizCreateRequests) {
        log.info("ReturnOrderBizAssembleOfCustomerCenter#query bizCreateRequests={}", JSON.toJSONString(bizCreateRequests));
        try {
            // 客户送达方
            Map<String, ShipToPartyByAccurateQueryDTO> shipToPartyMap = queryShipToPartyByAccurate(bizCreateRequests);
            // 客户售达方
            Map<String, SoldToPartyByAccurateQueryDTO> soldToPartyMap = querySoldToPartyByAccurate(bizCreateRequests);
            // 业务单元
            Map<String, DictionaryResponse> businessUnitMap = queryBusinessUnit();
            // 销售组织
            Map<String, String> salesOrgMap = querySalesOrgByCodeListV2(bizCreateRequests);
            // 销售部门
            Map<String, String> salesDeptMap = querySalesDeptByCodeList(bizCreateRequests);
            // 销售渠道
            Map<String, String> salesChannelMap = querySalesChannelByCodeList(bizCreateRequests);
            // 业务渠道
            Map<String, BusinessChannelDTO> bizChannelMap = queryBizChannelByCodeList(bizCreateRequests);

            Map<String, Object> result = Maps.newHashMap();
            result.put(SHIP_TO_PARTY, shipToPartyMap);
            result.put(SOLD_TO_PARTY, soldToPartyMap);
            result.put(BUSINESS_UNIT_CODE, businessUnitMap);
            result.put(SALES_ORGANIZATION, salesOrgMap);
            result.put(SALES_DEPARTMENT, salesDeptMap);
            result.put(SALES_CHANNEL, salesChannelMap);
            result.put(BUSINESS_CHANNEL, bizChannelMap);

            log.info("ReturnOrderBizAssembleOfCustomerCenter#query result={}", JSONObject.toJSONString(result));
            return result;
        } catch (Exception e) {
            log.error("ReturnOrderBizAssembleOfCustomerCenter#query error", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public Result<String> assemble(Map<String, Object> queryResponseMap, ReturnOrderBizCreateRequest bizCreateRequest) {
        log.info("ReturnOrderBizAssembleOfCustomerCenter#assemble queryResponseMap={} bizCreateRequest={}",
                JSON.toJSONString(queryResponseMap), JSON.toJSONString(bizCreateRequest));
        // 客户送达方
        Map<String, ShipToPartyByAccurateQueryDTO> shipToPartyMap = getBizInfoMap(queryResponseMap, SHIP_TO_PARTY, ShipToPartyByAccurateQueryDTO.class);
        // 客户售达方
        Map<String, SoldToPartyByAccurateQueryDTO> soldToPartyMap = getBizInfoMap(queryResponseMap, SOLD_TO_PARTY, SoldToPartyByAccurateQueryDTO.class);
        // 业务单元
//        Map<String, DictionaryResponse> businessUnitMap = getBizInfoMap(queryResponseMap, BUSINESS_UNIT_CODE, DictionaryResponse.class);
        // 销售组织
        Map<String, String> salesOrgMap = getBizInfoMap(queryResponseMap, SALES_ORGANIZATION, String.class);
        // 销售部门
        Map<String, String> salesDeptMap = getBizInfoMap(queryResponseMap, SALES_DEPARTMENT, String.class);
        // 销售渠道
        Map<String, String> salesChannelMap = getBizInfoMap(queryResponseMap, SALES_CHANNEL, String.class);
        // 业务渠道
        Map<String, BusinessChannelDTO> bizChannelMap = getBizInfoMap(queryResponseMap, BUSINESS_CHANNEL, BusinessChannelDTO.class);

        // 业务单元
//        DictionaryResponse businessUnit = businessUnitMap.get(bizCreateRequest.getBusinessUnitCode());
//        if (Objects.isNull(businessUnit)) {
//            return Result.fail(bizCreateRequest.getSourceOrderNo(), "OC-01-001-01-16-011", "业务单元编码不存在");
//        }
//        bizCreateRequest.setBusinessUnitName(businessUnit.getName());

        // 销售组织
//        String salesOrgKey = SalesOrgTypeEnum.SALES_ORG.getCode() + "_" + bizCreateRequest.getSalesOrganizationCode();
//        if (OrderCategoryEnum.GROUP.getCode().equals(bizCreateRequest.getOrderCategoryCode())) {
//            salesOrgKey = bizCreateRequest.getSalesOrganizationCode();
//        }
        String salesOrganizationName = salesOrgMap.get(bizCreateRequest.getSalesOrganizationCode());
        if (StringUtils.isBlank(salesOrganizationName)) {
            return Result.fail(bizCreateRequest.getSourceOrderNo(), "OC-01-001-01-16-034", "销售组织编码/名称不存在");
        }
        bizCreateRequest.setSalesOrganizationName(salesOrganizationName);

        // 销售部门
        if (StringUtils.isNotBlank(bizCreateRequest.getSalesDepartmentCode())) {
            String salesDepartmentName = salesDeptMap.get(bizCreateRequest.getSalesDepartmentCode());
            if (StringUtils.isBlank(salesDepartmentName)) {
                if (!OrderCategoryEnum.GROUP.getCode().equals(bizCreateRequest.getOrderCategoryCode())) {
                    return Result.fail(bizCreateRequest.getSourceOrderNo(), "OC-01-001-01-16-035", "销售部门编码/名称不存在");
                }
            } else {
                if (StringUtils.isBlank(bizCreateRequest.getSalesDepartmentName())) {
                    bizCreateRequest.setSalesDepartmentName(salesDepartmentName);
                }
            }
        }

        // 销售渠道
        if (StringUtils.isNotBlank(bizCreateRequest.getSalesChannelCode())) {
            String salesChannelName = salesChannelMap.get(bizCreateRequest.getSalesChannelCode());
            if (StringUtils.isBlank(salesChannelName)) {
                if (!OrderCategoryEnum.GROUP.getCode().equals(bizCreateRequest.getOrderCategoryCode())) {
                    return Result.fail(bizCreateRequest.getSourceOrderNo(), "OC-01-001-01-16-037", "销售渠道编码/名称不存在");
                }
            } else {
                if (StringUtils.isBlank(bizCreateRequest.getSalesChannelName())) {
                    bizCreateRequest.setSalesChannelName(salesChannelName);
                }
            }
        }

        // 业务渠道
        BusinessChannelDTO businessChannelDTO = bizChannelMap.get(bizCreateRequest.getBusinessChannel());
        if (Objects.isNull(businessChannelDTO)) {
            return Result.fail(bizCreateRequest.getSourceOrderNo(), "OC-01-001-01-16-051", "业务渠道不存在");
        }
        bizCreateRequest.setBusinessChannelName(businessChannelDTO.getChannelName());

        // 客户售达方
        SoldToPartyByAccurateQueryDTO soldToParty = soldToPartyMap.get(bizCreateRequest.getCustomerCode());
        if (Objects.isNull(soldToParty)) {
            return Result.fail(bizCreateRequest.getSourceOrderNo(), "OC-01-001-01-16-032", "售达方编码/名称不存在");
        }
        bizCreateRequest.setCustomerName(soldToParty.getSoldToPartyName());

        // 客户送达方
        ShipToPartyByAccurateQueryDTO shipToParty = shipToPartyMap.get(bizCreateRequest.getShipToPartyCode());
        if (Objects.isNull(shipToParty)) {
            return Result.fail(bizCreateRequest.getSourceOrderNo(), "OC-01-001-01-16-033", "送达方编码/名称不存在");
        }
        bizCreateRequest.setShipToPartyName(shipToParty.getShipToPartyName());
        if (OrderCategoryEnum.GROUP.getCode().equals(bizCreateRequest.getOrderCategoryCode())) {
            // 集团销售订单，若未传入，根据【产品组+业务渠道+销售组织+售达方+送达方】查询客户中心送达方档案，获取销售部门编码、名称、销售组编码、名称后保存
            if (StringUtils.isBlank(bizCreateRequest.getSalesChannelCode())) {
                bizCreateRequest.setSalesChannelCode(shipToParty.getOuterSalesDepartmentCode()); // 销售办公室
            }
            if (StringUtils.isBlank(bizCreateRequest.getSalesChannelName())) {
                bizCreateRequest.setSalesChannelName(shipToParty.getOuterSalesDepartment());
            }
            if (StringUtils.isBlank(bizCreateRequest.getSalesDepartmentCode())) {
                bizCreateRequest.setSalesDepartmentCode(shipToParty.getOuterSalesGroupCode()); // 销售组
            }
            if (StringUtils.isBlank(bizCreateRequest.getSalesDepartmentName())) {
                bizCreateRequest.setSalesDepartmentName(shipToParty.getOuterSalesGroup());
            }
        }

        return Result.success(null);
    }

    private Map<String, ShipToPartyByAccurateQueryDTO> queryShipToPartyByAccurate(List<ReturnOrderBizCreateRequest> bizCreateRequests) {
        List<ShipToPartyByAccurateQueryRequest> requests = Lists.newArrayList();

        for (ReturnOrderBizCreateRequest createRequest : bizCreateRequests) {

            ShipToPartyByAccurateQueryRequest queryRequest = new ShipToPartyByAccurateQueryRequest();
            queryRequest.setBusinessType(createRequest.getProductGroupCode());
            queryRequest.setBusinessUnitCode(createRequest.getBusinessUnitCode());
            queryRequest.setSalesOrganizationCode(createRequest.getSalesOrganizationCode());
            queryRequest.setShipToPartyCode(createRequest.getShipToPartyCode());
            queryRequest.setSoldToPartyCode(createRequest.getCustomerCode());
            queryRequest.setSalesChannelCode(createRequest.getBusinessChannel());

            requests.add(queryRequest);
        }
        if (CollectionUtils.isEmpty(requests)) {
            return Maps.newHashMap();
        }

        List<ShipToPartyByAccurateQueryDTO> listResult = shipToPartyAbilityAdapter.queryShipToPartyByAccurate(requests);

        if (CollectionUtils.isEmpty(listResult)) {
            return Maps.newHashMap();
        }

        return listResult.stream().collect(
                Collectors.toMap(ShipToPartyByAccurateQueryDTO::getShipToPartyCode, p -> p, (v1, v2) -> v1));
    }


    private Map<String, SoldToPartyByAccurateQueryDTO> querySoldToPartyByAccurate(List<ReturnOrderBizCreateRequest> bizCreateRequests) {
        List<SoldToPartyByAccurateQueryRequest> requests = Lists.newArrayList();

        for (ReturnOrderBizCreateRequest createRequest : bizCreateRequests) {

            SoldToPartyByAccurateQueryRequest queryRequest = new SoldToPartyByAccurateQueryRequest();
            queryRequest.setBusinessType(createRequest.getProductGroupCode());
            queryRequest.setBusinessUnitCode(createRequest.getBusinessUnitCode());
            queryRequest.setSalesOrganizationCode(createRequest.getSalesOrganizationCode());
            queryRequest.setShipToPartyCode(createRequest.getShipToPartyCode());
            queryRequest.setSoldToPartyCode(createRequest.getCustomerCode());
            queryRequest.setSalesChannelCode(createRequest.getBusinessChannel());

            requests.add(queryRequest);
        }

        if (CollectionUtils.isEmpty(requests)) {
            return Maps.newHashMap();
        }

        List<SoldToPartyByAccurateQueryDTO> listResult = soldToPartyAbilityAdapter.querySoldToPartyByAccurate(requests);

        if (CollectionUtils.isEmpty(listResult)) {
            return Maps.newHashMap();
        }

        return listResult.stream().collect(
                Collectors.toMap(SoldToPartyByAccurateQueryDTO::getSoldToPartyCode, p -> p, (v1, v2) -> v1));
    }

    private Map<String, DictionaryResponse> queryBusinessUnit() {
        Map<String, DictionaryResponse> businessUnitMap = new HashMap<>();
        List<DictionaryResponse> businessUnitList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.BUSINESS_UNIT_CODE.getCode());
        if (CollectionUtils.isNotEmpty(businessUnitList)) {
            businessUnitMap = businessUnitList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity(), (x1, x2) -> x2));
        }
        return businessUnitMap;
    }

    private Map<String, String> querySalesOrgByCodeListV2(List<ReturnOrderBizCreateRequest> bizCreateRequests) {
        List<String> codeList = bizCreateRequests.stream()
                .map(OrderAtomCreateRequest::getSalesOrganizationCode)
                .filter(StringUtils::isNotBlank).distinct()
                .collect(Collectors.toList());
        return customerCenterAdapter.querySalesOrganization(codeList);
    }

    private Map<String, String> querySalesDeptByCodeList(List<ReturnOrderBizCreateRequest> bizCreateRequests) {
        List<String> codeList = bizCreateRequests.stream()
                .map(OrderAtomCreateRequest::getSalesDepartmentCode)
                .filter(StringUtils::isNotBlank).distinct()
                .collect(Collectors.toList());
        return customerCenterAdapter.querySalesDepartment(codeList);
    }

    private Map<String, String> querySalesChannelByCodeList(List<ReturnOrderBizCreateRequest> bizCreateRequests) {
        List<String> codeList = bizCreateRequests.stream()
                .map(OrderAtomCreateRequest::getSalesChannelCode)
                .filter(StringUtils::isNotBlank).distinct()
                .collect(Collectors.toList());
        return customerCenterAdapter.querySalesChannel(codeList);
    }

    private Map<String, BusinessUnitDTO> queryBizUnitByCodeList(List<ReturnOrderBizCreateRequest> bizCreateRequests) {

        List<String> bizChannelCodeList = bizCreateRequests.stream()
                .map(OrderAtomCreateRequest::getBusinessUnitCode)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());

        List<BusinessUnitDTO> businessUnitDTOS = businessUnitAbilityAdapter.queryBusinessUnit(bizChannelCodeList);

        if (CollectionUtils.isEmpty(businessUnitDTOS)) {
            return Maps.newHashMap();
        }

        return businessUnitDTOS.stream().collect(Collectors.toMap(BusinessUnitDTO::getBusinessUnitCode, p -> p, (v1, v2) -> v1));
    }

    private Map<String, BusinessChannelDTO> queryBizChannelByCodeList(List<ReturnOrderBizCreateRequest> bizCreateRequests) {

        List<String> bizChannelCodeList = bizCreateRequests.stream()
                .map(OrderAtomCreateRequest::getBusinessChannel)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());

        List<BusinessChannelDTO> businessUnitDTOS = businessChannelAbilityAdapter.queryBusinessChannel(bizChannelCodeList);

        if (CollectionUtils.isEmpty(businessUnitDTOS)) {
            return Maps.newHashMap();
        }

        return businessUnitDTOS.stream().collect(Collectors.toMap(BusinessChannelDTO::getChannelCode, p -> p, (v1, v2) -> v1));
    }
}
